package com.example.campusannouncement.controller;

import com.example.campusannouncement.service.AnnouncementService;
import com.example.campusannouncement.entity.Announcement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Controller
@RequestMapping("/announcements")
public class AnnouncementController {
    private static final Logger logger = LoggerFactory.getLogger(AnnouncementController.class);

    @Autowired
    private AnnouncementService announcementService;

    // 获取所有公告页面（分页）
    @GetMapping
    public String listAnnouncements(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "publishDate") String sortBy,
            @RequestParam(defaultValue = "desc") String direction,
            Model model) {
        try {
            logger.info("访问公告列表页面 - page: {}, size: {}, sortBy: {}, direction: {}", 
                page, size, sortBy, direction);
            
            // 验证排序字段
            if (!isValidSortField(sortBy)) {
                logger.warn("无效的排序字段: {}", sortBy);
                sortBy = "publishDate";
            }

            Sort.Direction sortDirection = Sort.Direction.fromString(direction);
            PageRequest pageRequest = PageRequest.of(page, size, Sort.by(sortDirection, sortBy));
            
            Page<Announcement> announcements = announcementService.getAllAnnouncements(pageRequest);
            logger.info("成功获取公告列表，共 {} 条记录", announcements.getTotalElements());
            
            model.addAttribute("announcements", announcements);
            model.addAttribute("currentPage", page);
            model.addAttribute("totalPages", announcements.getTotalPages());
            model.addAttribute("totalItems", announcements.getTotalElements());
            model.addAttribute("sortBy", sortBy);
            model.addAttribute("direction", direction);
            
            return "announcement-list";
        } catch (Exception e) {
            logger.error("获取公告列表失败", e);
            model.addAttribute("error", "获取公告列表失败：" + e.getMessage());
            return "error";
        }
    }

    // 验证排序字段
    private boolean isValidSortField(String field) {
        return field != null && (field.equals("publishDate") || 
                               field.equals("title") || 
                               field.equals("author"));
    }

    // 新增公告页面
    @GetMapping("/add")
    public String showAddForm(Model model) {
        try {
            logger.info("访问新增公告页面");
            model.addAttribute("announcement", new Announcement());
            return "announcement-add";
        } catch (Exception e) {
            logger.error("访问新增公告页面失败", e);
            model.addAttribute("error", "访问新增公告页面失败：" + e.getMessage());
            return "error";
        }
    }

    // 保存新增公告
    @PostMapping("/add")
    public String saveAnnouncement(@ModelAttribute Announcement announcement,
                                 @RequestParam(value = "attachment", required = false) MultipartFile file,
                                 @RequestParam(value = "publishDateStr", required = false) String publishDateStr,
                                 RedirectAttributes redirectAttributes,
                                 Model model) {
        try {
            logger.info("保存新公告开始: {}", announcement.getTitle());
            logger.debug("接收到的公告数据: title={}, content={}, author={}, publishDate={}, publishDateStr={}, status={}",
                      announcement.getTitle(), 
                      announcement.getContent() != null ? announcement.getContent().substring(0, Math.min(20, announcement.getContent().length())) + "..." : null,
                      announcement.getAuthor(),
                      announcement.getPublishDate(),
                      publishDateStr,
                      announcement.getStatus());
            
            // 处理日期格式转换
            if (publishDateStr != null && !publishDateStr.isEmpty()) {
                try {
                    // 将HTML datetime-local格式转换为Date
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm");
                    Date publishDate = dateFormat.parse(publishDateStr);
                    announcement.setPublishDate(publishDate);
                    logger.info("日期格式转换成功: {}", publishDate);
                } catch (ParseException e) {
                    logger.error("日期格式转换失败: {}", e.getMessage());
                    throw new IllegalArgumentException("发布日期格式不正确，请使用正确的日期时间格式");
                }
            }
            
            // 验证必填字段
            if (announcement.getTitle() == null || announcement.getTitle().trim().isEmpty()) {
                throw new IllegalArgumentException("标题不能为空");
            }
            if (announcement.getContent() == null || announcement.getContent().trim().isEmpty()) {
                throw new IllegalArgumentException("内容不能为空");
            }
            if (announcement.getAuthor() == null || announcement.getAuthor().trim().isEmpty()) {
                throw new IllegalArgumentException("作者不能为空");
            }
            if (announcement.getPublishDate() == null) {
                throw new IllegalArgumentException("发布日期不能为空");
            }
            if (announcement.getStatus() == null) {
                logger.info("状态为空，设置默认状态为ACTIVE");
                announcement.setStatus(Announcement.Status.ACTIVE);
            }
            
            // 处理文件上传
            if (file != null && !file.isEmpty()) {
                logger.info("处理文件上传: {}, 大小: {}", file.getOriginalFilename(), file.getSize());
                String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
                String uploadDir = System.getProperty("user.dir") + "/uploads";
                File dir = new File(uploadDir);
                if (!dir.exists()) {
                    logger.info("创建上传目录: {}", uploadDir);
                    dir.mkdirs();
                }
                File destFile = new File(dir, fileName);
                file.transferTo(destFile);
                announcement.setAttachmentPath("uploads/" + fileName);
                logger.info("文件上传成功: {}", destFile.getAbsolutePath());
            } else {
                logger.info("没有上传文件或文件为空");
            }
            
            Announcement saved = announcementService.createAnnouncement(announcement);
            logger.info("公告保存成功，ID: {}", saved.getId());
            redirectAttributes.addFlashAttribute("success", "公告创建成功！");
            return "redirect:/announcements";
        } catch (IllegalArgumentException e) {
            logger.error("保存公告失败 - 参数错误: {}", e.getMessage());
            // 直接返回错误到当前页面，而不是重定向
            model.addAttribute("error", e.getMessage());
            model.addAttribute("announcement", announcement);
            return "announcement-add";
        } catch (Exception e) {
            logger.error("保存公告失败", e);
            // 直接返回错误到当前页面，而不是重定向
            model.addAttribute("error", "保存公告失败：" + e.getMessage());
            model.addAttribute("announcement", announcement);
            return "announcement-add";
        }
    }

    // 编辑公告页面
    @GetMapping("/edit/{id}")
    public String showEditForm(@PathVariable Long id, Model model) {
        try {
            logger.info("访问编辑公告页面，ID: {}", id);
            Optional<Announcement> announcement = announcementService.getAnnouncementById(id);
            if (announcement.isPresent()) {
                model.addAttribute("announcement", announcement.get());
                return "announcement-edit";
            } else {
                logger.warn("公告不存在，ID: {}", id);
                return "redirect:/announcements?error=公告不存在";
            }
        } catch (Exception e) {
            logger.error("访问编辑公告页面失败", e);
            model.addAttribute("error", "访问编辑公告页面失败：" + e.getMessage());
            return "error";
        }
    }

    // 更新公告
    @PostMapping("/edit/{id}")
    public String updateAnnouncement(@PathVariable Long id, 
                                   @ModelAttribute Announcement updatedAnnouncement,
                                   @RequestParam(value = "publishDateStr", required = false) String publishDateStr,
                                   RedirectAttributes redirectAttributes,
                                   Model model) {
        try {
            logger.info("更新公告，ID: {}", id);
            
            // 处理日期格式转换
            if (publishDateStr != null && !publishDateStr.isEmpty()) {
                try {
                    // 将HTML datetime-local格式转换为Date
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm");
                    Date publishDate = dateFormat.parse(publishDateStr);
                    updatedAnnouncement.setPublishDate(publishDate);
                    logger.info("日期格式转换成功: {}", publishDate);
                } catch (ParseException e) {
                    logger.error("日期格式转换失败: {}", e.getMessage());
                    model.addAttribute("error", "发布日期格式不正确，请使用正确的日期时间格式");
                    model.addAttribute("announcement", updatedAnnouncement);
                    return "announcement-edit";
                }
            }
            
            Announcement updated = announcementService.updateAnnouncement(id, updatedAnnouncement);
            logger.info("公告更新成功，ID: {}", updated.getId());
            redirectAttributes.addFlashAttribute("success", "公告更新成功！");
            return "redirect:/announcements";
        } catch (Exception e) {
            logger.error("更新公告失败", e);
            model.addAttribute("error", "更新公告失败：" + e.getMessage());
            model.addAttribute("announcement", updatedAnnouncement);
            return "announcement-edit";
        }
    }

    // 删除公告
    @GetMapping("/delete/{id}")
    public String deleteAnnouncement(@PathVariable Long id, RedirectAttributes redirectAttributes) {
        try {
            logger.info("删除公告，ID: {}", id);
            announcementService.deleteAnnouncement(id);
            logger.info("公告删除成功，ID: {}", id);
            redirectAttributes.addFlashAttribute("success", "公告删除成功！");
            return "redirect:/announcements";
        } catch (Exception e) {
            logger.error("删除公告失败", e);
            redirectAttributes.addFlashAttribute("error", "删除公告失败：" + e.getMessage());
            return "redirect:/announcements";
        }
    }

    // 搜索公告
    @GetMapping("/search")
    public String searchAnnouncements(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            Model model) {
        try {
            logger.info("搜索公告，关键词: {}, page: {}, size: {}", keyword, page, size);
            PageRequest pageRequest = PageRequest.of(page, size);
            Page<Announcement> announcements = announcementService.searchAnnouncements(keyword, pageRequest);
            logger.info("搜索完成，找到 {} 条记录", announcements.getTotalElements());
            
            model.addAttribute("announcements", announcements);
            model.addAttribute("keyword", keyword);
            model.addAttribute("currentPage", page);
            model.addAttribute("totalPages", announcements.getTotalPages());
            model.addAttribute("totalItems", announcements.getTotalElements());
            return "announcement-list";
        } catch (Exception e) {
            logger.error("搜索公告失败", e);
            model.addAttribute("error", "搜索公告失败：" + e.getMessage());
            return "error";
        }
    }

    // 批量删除公告
    @PostMapping("/delete/batch")
    @ResponseBody
    public ResponseEntity<String> deleteAnnouncements(@RequestBody List<Long> ids) {
        try {
            announcementService.deleteAnnouncements(ids);
            return new ResponseEntity<>("Successfully deleted announcements", HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    // RESTful API endpoints
    @GetMapping("/{id}")
    @ResponseBody
    public ResponseEntity<Announcement> getAnnouncementById(@PathVariable Long id) {
        Optional<Announcement> announcement = announcementService.getAnnouncementById(id);
        return announcement.map(value -> new ResponseEntity<>(value, HttpStatus.OK))
                .orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    @PostMapping
    @ResponseBody
    public ResponseEntity<Announcement> saveAnnouncementRest(@RequestBody Announcement announcement) {
        Announcement savedAnnouncement = announcementService.createAnnouncement(announcement);
        return new ResponseEntity<>(savedAnnouncement, HttpStatus.CREATED);
    }

    @DeleteMapping("/{id}")
    @ResponseBody
    public ResponseEntity<Void> deleteAnnouncementRest(@PathVariable Long id) {
        try {
            announcementService.deleteAnnouncement(id);
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        } catch (RuntimeException e) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }

    @PutMapping("/{id}")
    @ResponseBody
    public ResponseEntity<Announcement> updateAnnouncementRest(@PathVariable Long id, @RequestBody Announcement updatedAnnouncement) {
        try {
            Announcement announcement = announcementService.updateAnnouncement(id, updatedAnnouncement);
            return new ResponseEntity<>(announcement, HttpStatus.OK);
        } catch (RuntimeException e) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }
}